import { type RouteRecordRaw } from 'vue-router'
import { RootRoute, addRoutes } from './index'
import { useKeepALiveNamesOut } from '@/stores/modules/keepAliveNames'
import HomePageRoute from './modules/home'
import { ErrorPageRoute, NoPermissionPageRoute } from './static-routes'
import { useAsyncRouteStoreWidthOut } from '@/stores/modules/router'
import { useTagsViewRoutesOut } from '@/stores/modules/tagsViewRoutes'
import { deepClone } from '@/utils/Index'
// 获取所有路由数据
const routeModuleList: RouteRecordRaw[] = []
const modules: any = import.meta.glob('./modules/**/*.ts', { eager: true })
Object.keys(modules).forEach(key => {
  // if (key && key != './modules/dashboard.ts') {
  const mod = modules[key].default || {}
  const modList = Array.isArray(mod) ? [...mod] : [mod]
  routeModuleList.push(...modList)
  // }
})
function sortRoute(a: any, b: any) {
  return (a || 0) - (b || 0)
}
routeModuleList.sort(sortRoute)
export const asyncRoutes = [...routeModuleList]
// 获取所有的路由页面
const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}', {
  eager: true
})
const viewsModules: any = import.meta.glob('../views/**/*.{vue,tsx}', {
  eager: true
})
const dynamicViewsModules: Record<string, () => Promise<Recordable>> =
  Object.assign({}, { ...layouModules }, { ...viewsModules })

export async function handleRouterResponse(dat: string[]) {
  const routeList: any[] = []
  for (const str of dat) {
    for (const route of asyncRoutes) {
      // 没有下级菜单直接添加
      if (!route.children && str == route.path) {
        routeList.push(route)
        break
      }
      const isFinish = handleChildrenRoute(route, null, str, routeList)
      if (isFinish) {
        break
      }
    }
  }
  return routeList
}
function handleChildrenRoute(
  route: any,
  parent: any,
  str: string,
  list: any[]
) {
  if (!route) return false
  if (route && route.children) {
    const obj = route.children.find((item: any) => item.path == str)
    if (obj) {
      const hasRoute = getListElement(list, route.path)
      if (hasRoute) {
        hasRoute.children.push(obj)
        return true
      } else {
        if (parent) {
          const hasParentRoute = getListElement(list, parent.path)
          if (hasParentRoute) {
            const subRoute: any = deepClone(route)
            subRoute.children = [obj]
            hasParentRoute.children.push(subRoute)
            return true
          } else {
            const parentRoute: any = deepClone(parent)
            const subRoute: any = deepClone(route)
            subRoute.children = [obj]
            parentRoute.children = [subRoute]
            list.push(parentRoute)
            return true
          }
        } else {
          const copyRoute: any = deepClone(route)
          copyRoute.children = [obj]
          list.push(copyRoute)
          return true
        }
      }
      // }
    } else {
      for (let index = 0; index < route.children.length; index++) {
        const element = route.children[index]
        handleChildrenRoute(element, route, str, list)
      }
    }
  }
  return false
}
// 获取列表元素
function getListElement(list: any[], key: string) {
  if (!list || list.length == 0) return null
  const arr = formatFlatteningRoutes(list)
  return arr.find((item: any) => item.path == key)
}
// 格式化生成路由
export async function routerGenerator(routes: any) {
  if (!routes) return null
  var isHasHome = false
  routes.forEach((v: any) => {
    if (isHasHome) return
    if (v.path === '/home') {
      isHasHome = true
    }
  })
  if (!isHasHome) {
    routes = [...HomePageRoute, ...routes]
  }
  const childrenList = handleRouteImport(routes)
  RootRoute.children = childrenList
  // 添加路由
  const list = await addPageToRoute()
  // 设置路由至缓存
  const asyncRouteStore = useAsyncRouteStoreWidthOut()
  asyncRouteStore.setRoutesList(childrenList)
  const tagsViewRoutes = useTagsViewRoutesOut()
  const tags = formatFlatteningRoutes(childrenList)
  tagsViewRoutes.setTagsViewRoutes(tags)
  return list
}
// 处理路由数据
const handleRouteImport = (routes: any): any[] => {
  if (!routes) return []
  return routes.map((item: any) => {
    if (item.component) {
      const mod: any = dynamicImport(
        dynamicViewsModules,
        item.component as string
      )
      if (mod && mod.default) {
        item.component = mod.default
      } else {
        item.component = mod
      }
    }
    item.children && handleRouteImport(item.children)
    return item
  })
}

async function addPageToRoute() {
  const arr = [RootRoute]
  // 转化成一维路由
  const routeList = formatFlatteningRoutes(arr)
  // 转化成二维路由
  const list: any = formatTwoStageRoutes(routeList) || []
  if (list && list.length > 0) {
    list[0].children = [
      ...list[0].children,
      ErrorPageRoute,
      NoPermissionPageRoute
    ]
  } else {
    list[0].children = [ErrorPageRoute, NoPermissionPageRoute]
  }
  await addRoutes(list)
  return list
}

/**
 * 动态导入
 * */
export const dynamicImport = (
  viewsModules: Record<string, Function>,
  component: string
) => {
  const keys = Object.keys(viewsModules)
  const matchKeys = keys.filter(key => {
    let k = key.replace('../views', '')
    const lastIndex = k.lastIndexOf('.')
    k = k.substring(0, lastIndex)
    // return k.startsWith(`${component}`) || k.startsWith(`${component}`)
    return k === component
  })
  if (matchKeys?.length === 1) {
    const matchKey = matchKeys[0]
    return dynamicViewsModules[matchKey]
  }
  if (matchKeys?.length > 1) {
    return false
  }
}

/**
 * 路由多级嵌套数组处理成一维数组
 * @param arr 传入路由菜单数据数组
 * @returns 返回处理后的一维路由菜单数组
 */
export function formatFlatteningRoutes(arr: any) {
  if (arr.length <= 0) return false
  for (let i = 0; i < arr.length; i++) {
    if (arr[i].children) {
      arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1))
    }
  }
  return arr
}

/**
 * 一维数组处理成多级嵌套数组（只保留二级：也就是二级以上全部处理成只有二级，keep-alive 支持二级缓存）
 * @description isKeepAlive 处理 `name` 值，进行缓存。顶级关闭，全部不缓存
 * @link 参考：https://v3.cn.vuejs.org/api/built-in-components.html#keep-alive
 * @param arr 处理后的一维路由菜单数组
 * @returns 返回将一维数组重新处理成 `定义动态路由（dynamicRoutes）` 的格式
 */
function formatTwoStageRoutes(arr: any) {
  if (arr.length <= 0) return false
  const newArr: any = []
  const cacheList: Array<string> = []
  arr.forEach((v: any) => {
    if (v.path === '/') {
      newArr.push({
        component: v.component,
        name: v.name,
        path: v.path,
        redirect: v.redirect,
        meta: v.meta,
        children: []
      })
    } else {
      // 判断是否是动态路由（xx/:id/:name），用于 tagsView 等中使用
      // 修复：https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
      if (v.path.indexOf('/:') > -1) {
        v.meta['isDynamic'] = true
        v.meta['isDynamicPath'] = v.path
      }
      newArr[0].children.push({ ...v })
      // 存 name 值，keep-alive 中 include 使用，实现路由的缓存
      // 路径：/@/layout/routerView/parent.vue
      if (newArr[0].meta.isKeepAlive && v.meta.isKeepAlive) {
        cacheList.push(v.name)
        const stores = useKeepALiveNamesOut()
        stores.setCacheKeepAlive(cacheList)
      }
    }
  })
  return newArr
}
